<template>
  <div>
    <a-page-header
        style="border: 1px solid rgb(235, 237, 240)"
        title="试卷管理"
        sub-title="新增、修改比赛"
        @back="() => $router.go(-1)"
    >
      <template slot="extra">
        <a-input-search key="0" v-model="search.key" placeholder="请输入关键词" style="width: 200px" @search="loadData" />
        <a-button key="1" type="primary" icon="plus" @click="onShowAdd">
          新增比赛
        </a-button>
      </template>
      <a-row type="flex">
        <a-statistic title="全部" suffix="场" :value="count.all" style="margin: 0 32px;"/>
        <a-statistic title="未开始" suffix="场" :value="count.start" style="margin: 0 32px;"/>
        <a-statistic title="进行中" suffix="场" :value="count.going" style="margin: 0 32px;"/>
        <a-statistic title="已结束" suffix="场" :value="count.over" style="margin: 0 32px;"/>
      </a-row>
      <template slot="footer">
        <a-table
            :columns="columns"
            :scroll="{ x: 1000 }"
            size="middle"
            :pagination="false"
            :dataSource="dataSource"
            :loading="loading"
        >
          <span slot="title" slot-scope="title">
            <a-tag :color="tag.color" v-for="(tag, index) in title.tags" v-bind:key="index">{{tag.text}}</a-tag>{{title.text}}
          </span>
          <span slot="type" slot-scope="type">
            <a-tag :color="type.color" >{{type.text}}</a-tag>
          </span>
          <span slot="score" slot-scope="score">
            <a-progress strokeColor="#66ffcc" :percent="maxScore?(score/maxScore*100):0" size="small" :format="()=>score"/>
          </span>
          <span slot="questionCount" slot-scope="questionCount">

              <a-popover title="题量">
                <template slot="content">
                  <p>填空题: {{questionCount.fillCount}}</p>
                  <p>判断题: {{questionCount.judgeCount}}</p>
                  <p>单选题: {{questionCount.radioCount}}</p>
                  <p>多选题: {{questionCount.multipleCount}}</p>
                </template>
                <a-progress strokeColor="#66ccff" :percent="maxQuestionCount?(questionCount.all/maxQuestionCount*100):0" size="small" :format="()=>questionCount.all"/>
              </a-popover>
          </span>
          <span slot="times" slot-scope="times">
            <a-progress strokeColor="#ccff66" :percent="maxTimes?(times/maxTimes*100):0" size="small" :format="()=>times"/>
          </span>
          <span slot="joinCount" slot-scope="joinCount">
            <a-progress strokeColor="#ffcc66" :percent="userCount?(joinCount/userCount*100):0" size="small" :format="()=>joinCount"/>
          </span>
          <span slot="joinRatio" slot-scope="joinRatio">
            <a-progress strokeColor="#cc66ff" :percent="joinRatio" size="small"/>
          </span>
          <span slot="action" slot-scope="record">
            <router-link :to="'/rank?exam=' + record.id">
              <a>排行榜</a>
            </router-link>
            <a-divider type="vertical"/>
            <a @click="onShowEdit(record.id)">修改</a>
            <a-divider type="vertical"/>
            <a style="color: #eb1c25" @click="onDeleteItem(record.id)">删除</a>
          </span>
        </a-table>
        <br>
        <a-config-provider :locale="zhCN">
          <a-pagination size="small" :total="total" show-size-changer show-quick-jumper :pageSizeOptions="['10', '30', '50', '100']" @change="changePage" @showSizeChange="changeSize"/>
        </a-config-provider>
        <br>
      </template>
    </a-page-header>
    <a-config-provider :locale="zhCN">
    <a-modal :title="`${currentPaper?'修改':'添加'}比赛 (总分: ${questionScore})`" :width="1200" :visible="showAdd" :body-style="{ paddingBottom: '80px' }" :ok-text="currentPaper?'修改':'添加'" cancel-text="取消" @ok="onSubmitPaper" @cancel="onCloseAdd" :ok-button-props="{ props: { disabled: errMsg.length > 0 , loading: btnAddLoading} }">
      <a-form-model ref="ruleForm" layout="vertical" :model="formData">
        <a-row>
          <a-col :span="24">
            <a-form-model-item required label="标题">
              <a-input type="textarea" v-model="formData.title" placeholder="请输入标题(100字以内)"/>
            </a-form-model-item>
          </a-col>
          <a-col :xs="24" :sm="12" :md="6">
            <a-form-model-item required label="比赛日期">
              <a-date-picker v-model="formData.date"/>
            </a-form-model-item>
          </a-col>
          <a-col :xs="24" :sm="12" :md="6">
            <a-form-model-item required label="时长">
              <a-time-picker v-model="formData.time" format="HH:mm" :minute-step="5"/>
            </a-form-model-item>
          </a-col>
          <a-col :xs="24" :sm="12" :md="6">
            <a-form-model-item required label="开始时间">
              <a-time-picker v-model="formData.startTime" format="HH:mm" :minute-step="5"/>
            </a-form-model-item>
          </a-col>
          <a-col :xs="24" :sm="12" :md="6">
            <a-form-model-item required label="结束时间">
              <a-time-picker v-model="formData.endTime" format="HH:mm" :minute-step="5"/>
            </a-form-model-item>
          </a-col>
        </a-row>
        <a-row>
          <a-col :xs="24" :sm="12" :md="6">
            <a-form-model-item required label="答题次数">
              <a-input-number v-model="formData.times" :min="1" :max="5" :formatter="value => `${value} 次`" style="margin-right: 10px;"/>
            </a-form-model-item>
          </a-col>
          <a-col :xs="24" :sm="12" :md="6">
            <a-form-model-item required label="算分方式">
              <a-radio-group button-style="solid" v-model="formData.scoreType" :disabled="formData.times === 1">
                <a-radio-button :value="0">
                  平均值
                </a-radio-button>
                <a-radio-button :value="1">
                  最大值
                </a-radio-button>
                <a-radio-button :value="2">
                  最小值
                </a-radio-button>
              </a-radio-group>
            </a-form-model-item>
          </a-col>
          <a-col :xs="24" :sm="12" :md="6">
            <a-form-model-item required label="题目随机">
              <a-switch v-model="formData.randomQuestions">
                <a-icon slot="checkedChildren" type="check" />
                <a-icon slot="unCheckedChildren" type="close" />
              </a-switch>
            </a-form-model-item>
          </a-col>
          <a-col :xs="24" :sm="12" :md="6">
            <a-form-model-item required label="选项随机">
              <a-switch v-model="formData.randomOptions" :disabled="formData.radioCount === 0 && formData.multipleCount === 0">
                <a-icon slot="checkedChildren" type="check" />
                <a-icon slot="unCheckedChildren" type="close" />
              </a-switch>
            </a-form-model-item>
          </a-col>
        </a-row>
        <a-row>
          <a-col :xs="24" :sm="12" :md="6">
            <a-form-model-item required label="判断题数量/分值">
              <a-input-number v-model="formData.judgeCount" :min="0" :max="100" :formatter="value => `${value} 道`" style="margin-right: 10px;"/>
              <a-input-number v-model="formData.judgeScore" :min="1" :max="10" :formatter="value => `${value} 分`" :disabled="formData.judgeCount===0"/>
            </a-form-model-item>
          </a-col>
          <a-col :xs="24" :sm="12" :md="6">
            <a-form-model-item required label="单选题数量/分值">
              <a-input-number v-model="formData.radioCount" :min="0" :max="100" :formatter="value => `${value} 道`" style="margin-right: 10px;"/>
              <a-input-number v-model="formData.radioScore" :min="1" :max="10" :formatter="value => `${value} 分`" :disabled="formData.radioCount===0"/>
            </a-form-model-item>
          </a-col>
          <a-col :xs="24" :sm="12" :md="6">
            <a-form-model-item required label="多选题数量/分值">
              <a-input-number v-model="formData.multipleCount" :min="0" :max="100" :formatter="value => `${value} 道`" style="margin-right: 10px;"/>
              <a-input-number v-model="formData.multipleScore" :min="1" :max="10" :formatter="value => `${value} 分`" :disabled="formData.multipleCount===0"/>
            </a-form-model-item>
          </a-col>
          <a-col :xs="24" :sm="12" :md="6">
            <a-form-model-item required label="填空题数量/分值">
              <a-input-number v-model="formData.fillCount" :min="0" :max="100" :formatter="value => `${value} 道`" style="margin-right: 10px;"/>
              <a-input-number v-model="formData.fillScore" :min="1" :max="10" :formatter="value => `${value} 分`" :disabled="formData.fillCount===0"/>
            </a-form-model-item>
          </a-col>
          <a-col :span="24" >
            <a-form-model-item required label="题目">
              <a-transfer
                  class="tree-transfer"
                  :list-style="{
                minHeight: '300px',
                }"
                  show-search
                  :data-source="allQuestions"
                  :titles="['所有', '已选择']"
                  :target-keys="targetQuestions"
                  :selected-keys="selectedQuestions"
                  :filter-option="(inputValue, item) => (item.title + item.typeStr.text).indexOf(inputValue) !== -1"
                  :render="renderItem"
                  @change="handleChange"
                  @selectChange="handleSelectChange"
              />
            </a-form-model-item>
          </a-col>
        </a-row>
        <a-popover title="错误" v-if="errMsg.length > 0">
          <template slot="content">
            <a-alert :message="msg" type="error" show-icon v-for="(msg, index) in errMsg" v-bind:key="index" style="margin: 5px 0;"/>
          </template>
          <a-alert
              :message="`${errMsg.length}个错误`"
              type="error"
              show-icon
          />
        </a-popover>
      </a-form-model>
    </a-modal>
    </a-config-provider>
  </div>
</template>

<script>
import zhCN from 'ant-design-vue/es/locale-provider/zh_CN'
import moment from 'moment'
import global from "@/components/global";

const columns = [
  {
    title: "ID",
    dataIndex: "id",
    key: "id",
    width: "3em",
    fixed: 'left',
  },
  {
    title: "创建时间",
    dataIndex: "createTime",
    key: "createTime",
    width: "10em",
    ellipsis: true,
  },
  {
    title: "创建者",
    dataIndex: "creator",
    key: "creator",
    width: "7em",
    ellipsis: true,
  },
  {
    title: "标题",
    dataIndex: "title",
    key: "title",
    width: "15em",
    ellipsis: true,
    scopedSlots: {customRender: "title"},
  },
  {
    title: "比赛时间",
    dataIndex: "period",
    key: "period",
    width: "13em",
    ellipsis: true,
  },
  {
    title: "限时",
    dataIndex: "time",
    key: "time",
    width: "7em",
    ellipsis: true,
  },
  {
    title: "总分",
    dataIndex: "score",
    key: "score",
    width: "7em",
    sorter: (a, b) => a.score - b.score,
    scopedSlots: {customRender: "score"},
  },
  {
    title: "题量",
    dataIndex: "questionCount",
    key: "questionCount",
    width: "7em",
    sorter: (a, b) => a.questionCount.all - b.questionCount.all,
    scopedSlots: {customRender: "questionCount"},
  },
  {
    title: "次数",
    dataIndex: "times",
    key: "times",
    width: "7em",
    sorter: (a, b) => a.times - b.times,
    scopedSlots: {customRender: "times"}
  },
  {
    title: "计分方式",
    dataIndex: "type",
    key: "type",
    width: "7em",
    ellipsis: true,
    scopedSlots: {customRender: "type"},
  },
  {
    title: '参与人数',
    dataIndex: "joinCount",
    key: "joinCount",
    width: "7em",
    sorter: (a, b) => a.joinCount - b.joinCount,
    scopedSlots: {customRender: "joinCount"},
  },
  {
    title: "参与率",
    dataIndex: "joinRatio",
    key: "joinRatio",
    width: "7em",
    sorter: (a, b) => a.joinRatio - b.joinRatio,
    scopedSlots: {customRender: "joinRatio"}
  },
  {
    title: "操作",
    key: "action",
    width: "15em",
    fixed: 'right',
    scopedSlots: {customRender: "action"},
  },
];
let date = moment().startOf('day')
date.add(1, 'days')
let startTime = moment(date)
startTime.add(8, 'hours')
let endTime = moment(date)
endTime.add(12, 'hours')
let time = moment(date)
time.add(1, 'hours')
let initFormData = {
  title: '新比赛',
  date,
  startTime,
  endTime,
  time,
  times: 1,
  scoreType: 0,
  randomQuestions: true,
  randomOptions: true,
  radioCount: 5,
  radioScore : 5,
  multipleCount: 5,
  multipleScore: 5,
  judgeCount : 5,
  judgeScore : 5,
  fillCount : 5,
  fillScore : 5,
  questions: []
}

export default {
  name: "paper",
  data(){

    return {
      zhCN,
      total: 0,
      search:{
        page: 0,
        size: 10,
        key: ''
      },
      columns: columns,
      dataSource: [],
      questions: [],
      targetQuestions: [],
      selectedQuestions: [],
      loading: false,
      showAdd: false,
      btnAddLoading: false,
      formData:{...initFormData},
      loadingQuestion: false,
      count: {
        all: 0,
        start: 0,
        over: 0,
        going: 0
      },

      currentPaper: null,
      sourcePapers: [],
      maxScore: 0,
      maxTimes: 0,
      maxQuestionCount: 0,
      maxQuestionScore: 0,
      maxJoinCount: 0,
      maxJoinRatio: 0,
      userCount: 0
    }
  },
  methods:{
    moment,
    onDeleteItem(id){
      let that = this
      this.$confirm({
        title: '提示',
        content: '删除操作将会连带删除该比赛的所有有关的组卷、答卷记录, 确定要删除吗?',
        okText: '确定',
        cancelText: '取消',
        onOk() {
          global.http(that, 'api/Paper/Delete?id=' + id, {
            successText: '删除成功',
            failText: '删除失败',
            success(){
              that.loadData()
            }
          })
        },
      });
    },
    onSubmitPaper(){
      let that = this
      let postData = JSON.parse(JSON.stringify(this.formData))
      postData.date = this.formData.date.format('YYYY-MM-DD')
      postData.startTime = `${postData.date}T${this.formData.startTime.format('HH:mm:ss')}`
      postData.endTime = `${postData.date}T${this.formData.endTime.format('HH:mm:ss')}`
      postData.time = this.formData.time.minutes() + this.formData.time.hour() * 60
      postData.questions = this.targetQuestions
      postData.type = this.formData.scoreType
      that.btnAddLoading = true
      if(this.currentPaper){
        postData.id = this.currentPaper.id
        global.http(this, 'api/Paper/Update', {
          data: postData,
          successText: '修改成功',
          failText: '修改失败',
          success(){
            that.showAdd = false
            that.loadData()
          },
          complete(){
            that.btnAddLoading = false
          }
        })      }else {
        global.http(this, 'api/Paper/Create', {
          data: postData,
          successText: '添加成功',
          failText: '添加失败',
          success(){
            that.showAdd = false
            that.loadData()
          },
          complete(){
            that.btnAddLoading = false
          }
        })
      }
    },
    onCloseAdd(){
      this.showAdd = false
    },
    onShowAdd(){
      this.currentPaper = null
      this.targetQuestions = []
      this.formData = {...initFormData}
      this.showAdd = true
    },
    onShowEdit(id){
      let that = this
      this.currentPaper = this.sourcePapers.filter(x=>x.id===id)[0]
      if(this.currentPaper){
        let formData = {...that.currentPaper}
        formData.scoreType = formData.type
        formData.date = moment(formData.date)
        formData.startTime = moment(formData.startTime)
        formData.endTime = moment(formData.endTime)
        let time = moment(formData.startTime).startOf('days')
        time.add(formData.time, 'minutes')
        formData.time = time
        this.formData = formData
        this.targetQuestions = formData.questions
        this.showAdd = true
      }
    },
    changeSize(page, size){
      this.search.page = page - 1
      this.search.size = size
      this.loadData()
    },
    changePage(page, size){
      this.search.page = page - 1
      this.search.size = size
      this.loadData()
    },
    handleChange(nextTargetKeys) {
      this.targetQuestions = nextTargetKeys;
    },
    handleSelectChange(sourceSelectedKeys, targetSelectedKeys) {
      this.selectedQuestions = [...sourceSelectedKeys, ...targetSelectedKeys];
    },
    renderItem(item) {
      const customLabel = (
          <span>
            {'#' + item.id + ' '}
            <a-tag color={item.typeStr.color}>
              {item.typeStr.text}
            </a-tag>{item.title}
          </span>
      );
      return {
        label: customLabel, // for displayed item
        value: item.title, // for title and filter matching
      };
    },
    loadQuestion(){
      let that = this
      that.loadingQuestion = true
      global.http(this, 'api/Paper/AllQuestion', {
        data: that.search,
        success(res){
          that.questions = res.data.map(x=>{
            x.key = x.id
            x.typeStr = {color: ['orange', 'pink', 'blue', 'cyan'][x.type], text: ['判断题', '单选题', '多选题', '填空题'][x.type]}
            return x
          })
        },
        complete(){
          that.loadingQuestion = false
        }
      })
    },
    loadData(){
      let that = this
      that.loading = true
      global.http(this, 'api/Paper/Search', {
        data: that.search,
        success(res){
          let now = new Date()
          res.data.papers = res.data.papers.map(x=>{
            let p = {...x, questions: res.data.examQuestions.filter(y=>y.examinationId === x.id).map(e=>e.questionId)}
            p.questions.sort((a, b) => a - b)
            return p
          })
          that.sourcePapers = JSON.parse(JSON.stringify(res.data.papers))
          that.userCount = res.data.userCount
          that.dataSource = res.data.papers.map(x=>{
            x.key = x.id
            x.title = {text: x.title, tags: []}
            if(now.getTime() < new Date(x.startTime).getTime()){
              x.title.tags.push({color: 'blue', text: '未开始'})
            }else if(now.getTime() > new Date(x.endTime).getTime()){
              x.title.tags.push({color: 'orange', text: '已结束'})
            }else{
              x.title.tags.push({color: 'green', text: '进行中'})
            }
            x.createTime = global.dateToYmdHm(x.createTime)
            x.startTime = global.dateToYmdHm(x.startTime)
            x.endTime = global.dateToYmdHm(x.endTime)
            x.score = x.judgeCount * x.judgeScore + x.radioCount * x.radioScore + x.multipleCount * x.multipleScore + x.fillCount * x.fillScore
            x.time = global.sToHms(x.time * 60)
            x.type = {type: x.type, text: ['平均值', '最大值', '最小值'][x.type], color: ['cyan', 'pink', 'orange'][x.type]}
            x.period = `${global.dateToMdDay(x.startTime)} ${global.dateToHm(x.startTime)} ~ ${global.dateToHm(x.endTime)}`
            x.questionCount = {all: x.fillCount + x.judgeCount + x.radioCount + x.multipleCount, fillCount: x.fillCount, judgeCount: x.judgeCount, radioCount: x.radioCount, multipleCount: x.multipleCount}
            x.joinCount = new Set(res.data.examPapers.filter(ep=>ep.examinationId===x.id).map(ep=>ep.userId)).size
            x.joinRatio = (x.joinCount / that.userCount * 100).toFixed(2)
            return x
          })
          that.count.all = res.data.all
          that.count.start = res.data.start
          that.count.over = res.data.over
          that.count.going = res.data.going
          that.total = res.data.total
          that.maxTimes = global.max(that.dataSource.map(x=>x.times))
          that.maxScore = global.max(that.dataSource.map(x=>x.score))
          that.maxQuestionCount = global.max(that.dataSource.map(x=>x.questionCount.all))
          console.log(that.dataSource)
        },
        complete(){
          that.loading = false
        }
      })

    }
  },
  computed:{
    errMsg(){
      let that = this
      let result = []
      global.strLenLimit(this.formData.title, 100) || result.push('标题需在1-100个字符之间')
      this.formData.date || result.push('日期为必填项')
      this.formData.time || result.push('时长为必填项')
      this.formData.startTime || result.push('开始时间为必填项')
      this.formData.endTime || result.push('结束时间为必填项')
      if(this.formData.date && this.formData.time && this.formData.startTime && this.formData.endTime){
        this.formData.date.diff(moment(), 'days') >= 0 || result.push(('比赛日期不可早于今天'))
        let d = this.formData.endTime.diff(this.formData.startTime, 'minutes')
        d > 1 || result.push('开始时间需早于结束时间')
        d > 1 && (this.formData.time.minutes() + this.formData.time.hour() * 60 < d || result.push('开始/结束时间差应大于比赛时长'))
      }
      this.questionCount > 0 || result.push('题目总数需大于0')
      if(this.formData.randomQuestions){
        this.allQuestions.filter(x=>x.type === 0 && that.targetQuestions.filter(y=>y===x.key).length > 0).length >= this.formData.judgeCount || result.push('判断题数量不足')
        this.allQuestions.filter(x=>x.type === 1 && that.targetQuestions.filter(y=>y===x.key).length > 0).length >= this.formData.radioCount || result.push('单选题数量不足')
        this.allQuestions.filter(x=>x.type === 2 && that.targetQuestions.filter(y=>y===x.key).length > 0).length >= this.formData.multipleCount || result.push('多选题数量不足')
        this.allQuestions.filter(x=>x.type === 3 && that.targetQuestions.filter(y=>y===x.key).length > 0).length >= this.formData.fillCount || result.push('填空题数量不足')
      }else {
        this.allQuestions.filter(x=>x.type === 0 && that.targetQuestions.filter(y=>y===x.key).length > 0).length === this.formData.judgeCount || result.push(`判断题数量应为 ${this.formData.judgeCount}`)
        this.allQuestions.filter(x=>x.type === 1 && that.targetQuestions.filter(y=>y===x.key).length > 0).length === this.formData.radioCount || result.push(`单选题数量应为 ${this.formData.radioCount}`)
        this.allQuestions.filter(x=>x.type === 2 && that.targetQuestions.filter(y=>y===x.key).length > 0).length === this.formData.multipleCount || result.push(`多选题数量应为 ${this.formData.multipleCount}`)
        this.allQuestions.filter(x=>x.type === 3 && that.targetQuestions.filter(y=>y===x.key).length > 0).length === this.formData.fillCount || result.push(`填空题数量应为 ${this.formData.fillCount}`)
      }
      return result
    },
    questionCount(){
      return this.formData.judgeCount + this.formData.radioCount + this.formData.multipleCount + this.formData.fillCount
    },
    questionScore(){
      return this.formData.judgeCount * this.formData.judgeScore + this.formData.radioCount * this.formData.radioScore + this.formData.multipleCount * this.formData.multipleScore + this.formData.fillCount * this.formData.fillScore
    },
    allQuestions(){
      let types = []
      this.formData.judgeCount > 0 && types.push(0)
      this.formData.radioCount > 0 && types.push(1)
      this.formData.multipleCount > 0 && types.push(2)
      this.formData.fillCount > 0 && types.push(3)
      return this.questions.filter(x=>types.indexOf(x.type)>=0)
    }
  },
  mounted() {
    this.loadData()
    this.loadQuestion()
  }
}
</script>

<style>
.tree-transfer .ant-transfer-list {
  width: calc(50% - 20px);
  flex: none;
}
</style>